Blueprint Help Send comments on this topic.
Creating Connection Mappings

Glossary Item Box

Overview

Every connection in a CLIP circuit has a mapping that specifies which elements in the consumer object are connected to which elements in the provider object.  When a connection is created, a default mapping is selected based on the dimensionality of the two end-points and as the dimensionality of the end-points is subsequently modified, the mapping is updated appropriately.  In most cases this default mapping is adequate but sometimes it is necessary to specify a different mapping and this is achieved using the Connection Editor.  Having changed the mapping from the default, it is no longer tied to the dimensionality of the end-points and will require manual updating.  This link can be re-established by resetting the mapping to its default value.

Connection Editor Dialog

You can override the automatically generated connection mapping using the Connection Editor Dialog. This allows you to modify from the default connection mapping or to define a completely new mapping. The dialog has options to add loops, switches and cases, and to specify the connections to be made for each.  The editor produces a "Signature" to be processed by the translator and this is displayed at the bottom of the dialog for advanced users.

NB. Any 'Repeat Count' specified in the Connection Properties window is not shown in the "Signature" box or the Editor, and is subsequently added around each 'ConnectTo' call.

 

 

The dialog has 4 main sections

  • Action Options
  • Mapping Tree
  • Edit Window
  • Signature

Action Options

The Action Options allows a number of signature constructs to be quickly defined

 

 

Add a loop - A loop will force the associated connection tree to be repeated a number of times 

Add a switch statement - allows a sub-tree of connections to be made depending on the the switch specifier

Add a case statement - defines the sub-tree to be made if the switch specifier matches any of the case values.

Add a connection statement

Reset everything back to the default (auto-generated settings)

Delete the selected entry (delete key can be used) and all of its child entries.

Move the selected item up/down (page up/page down keys can be used)

 

The options available will be dependent on the current selection.

 

Mapping Tree

The Mapping Tree shows the current structure of the connections. This is easier to visualise than the Connection Signature.

Selecting items within the tree enables the appropriate Actions and Edit Options.

 

Edit Window

The edit window allows the selected item in the Signature Tree to be edited. The format of the window is dependent on the selection.

No Selection/Main element Loop Selected

 

ConnectTo selected - enter the element number of the object to be connected to.

As well as numerical values the special values ^n (loop index), #n (connectee element index) (where n is a value) can be used. When multi-dimensional objects are being connected a comma-separated list should be specified.

 

Loop selected - enter the limit of the loop as a numeric value or a macro value 

Values entered will be shown in the tree as

 

Switch selected - enter the connector element value top switch on (#0,#1...)

 Values entered will be shown in the tree as

 

Case selected - enter the lower and upper values to be accepted

If either the minimum or maximum fields are left blank ( (none) ), the translator will omit code to test for the appropriate limits. If both are blank ( (none) ) the translator will omit both bounds tests, thus becoming a catch all (default) case.

Range cases specified in a switch are be processed in order. Thus if two ranges overlap the first will always be used. This allows less specific ranges to be applied after the more specific ones. In general a catch all remaining values (default, no min max values)  is often specified as the last case. To restrict a case to a specific value, users need to specify a min and max with the same value.

Values entered are shown on the tree as

Min 2           Max 5

Min (none)  Max 10

Min 7          Max (none)

Min (none)  Max (none)

 

Signature

 

The signature area shows the current connection signature and dimension from the connection tree.

The connection signature is automatically updated as the tree is modified and will be shown in Green the signature is complete and correct. However, if there are any errors or missing entries (ie a switch with no cases) it will be shown in Red.

The dimension field shows the last known connection dimension, it is not updated automatically as it can be set by the user. However, it is compared to an automatically calculated value. If the shown dimension is the same as the calculated value or is a plausible variation of the calculated value, it is shown in White. Otherwise the dimension is shown in Red.

Pressing the  button will cause the calculated value to be displayed, replacing any previous calculated or user input.

If the connection signature contains a set of switches or loops than mean that a single dimension value cannot be calculated, a value of [*] is used and the code generator will generate an access function with one argument (plus any repeat count). It is up to the user to decode the connection structure to get to the required single element number. The generated code will not generate any dimension checking logic.

Eg

       switch

          case 1

             connect to element 1;

          case 2

             connect to elements 1 and 2;

         ...

         case N

             connect to elements 1..N.

 

In this instance there are different dimensions for each case (1, 2, N). Thus the user code must check for the connector object element number and pass the appropriate connection element number to the access function.

 

When no connection dimension can be calculated, any user specified connection dimension will be a plausible variation on the calculated value. To highlight this condition the dimension field will be shown in Orange. Similarly, a displayed/user specified value of [*] will also be shown in Orange IF the calculated value is NOT [*].

When the circuit is translated the dimension is compared to the calculated dimension. If the dimensions differ, a warning or error will be generated. Warnings are generated if there is a plausible mismatch, whilst errors are generated if there is an implausible/dangerous mismatch.

Eg. 

      Calculated Dimension       User Specified Dimension        Condition               Comments

                  [*]                                       [2][4]                         Warning        User is assumed to know best, but dimension may not been updated after a signature change

                  [9]                                       [3][3]                         Warning        Splitting a dimension is allowable, but dimension may not have been updated

                  [3][3]                                   [9]                             Warning        Combining a dimension is allowable, but dimension may not have been updated

                  [4][3]                                   [2][6]                          Error            Splitting one dimension and combining with another is not recommended

                  [2][9][4]                              [9][8]                           Error            Combining (or splitting) non-adjacent dimensions is not recommended

                  [10]                                     [3][3]                           Error            Dimension mismatch

                  [N]                                       [2]                               Error            Dimension mismatch

                  [3][4][2]                              [4][3][2]                      Error            Dimension reordering is not recommended

                  [N][2]                                  [N*2]                           Error            Can only combine (or split) numeric dimensions

 

There are a number of conditions where it is not possible to generate a regular dimension structure from a signature. This usually occurs when there are different connection structures within switch cases, or flat loops (as opposed to nested loops) with different loop sizes or internal structures.

Examples

 

The dialog above shows a user defined connection for two 2-d objects.

 

 This signature would generate the following code

for #1 in M
   for #0 in N

      switch ( #1 )
         case 0..1:
            Connect [#1,#0] to [0,0]
         case 2..M-1:
            Connect [#1,#0] to [1,1]  

 

Note: the generated code will always generate a loop for each dimension of the connecting object, even if the signature only specifies a switch on one of the loop variables. Thus each of the inner Ns will make the same connection profile. To restrict the connections to 'a single element connecting to a single element' would require a double switch in the signature

 

           <#1>{<1,1><#0>{<0,0>[3,4]}}

 

for #1 in M
   for #0 in N

      switch ( #1 )
         case 1..1:
            switch ( #0 )
               case 0..0:
                  Connect [#1,#0] to [3,4]

 

Irregular Connections

In some cases an even more advanced connection logic is required that cannot be defined by simple loops and switches. To this end Blueprint allows irregular connections to be defined via user defined macro functions.

In the following examples the an array of consumer objects only requires connections to a sub set of the provider objects (both same dimension). The first is a 1-d example, the second a 2-d example.

 

Example 1

The 1-d Collector is required to make a sub set of connections to the semaphore, depending on its element number.

 

 

Each collector element 'n' connects to a pair of Counting Semaphores 'n' and 'n+1'.  However, if 'n' is odd it must connect to element 'n' then 'n+1', if even it must connect in the opposite order 'n+1' then 'n'. When 'n+1' is greater then the number of elements, it must wrap around to element 0.

If NP is known then this connection 'could' be configured using the switch mechanism, but this could be cumbersome and prone to errors, especially if NP was to be changed. To make this connection using macros we need to generate two macro functions 'First()', 'Second()', and make connections using these.

 

 

These functions can be defined in the ProjectHeader.hpp file. Each function generates a single element number.

#define NP 7

#define First( X )  ( ((X)%2) ? (X) : (((X)+1)%NP) )  // if odd connect to X   else X+1 - wrap X+1 to 0 if required
#define Second( X ) ( ((X)%2) ? (((X)+1)%NP) : (X) )  // if odd connect to X+1 else X   - wrap X+1 to 0 if required

 

In this example the arguments to the macros are simply the loop variable, but this not a restriction. We could have passed other parameters into the macro

Eg.

#define Next( N, X, Y )   ( ((N)==1)  ?  ( ((X)%2) ? (X) : ( ((X)+1) % (Y) ) )   :   ( ((X)%2) ? ( ((X)+1) % (Y) ) : (X) )  )

ConnectTo( Next( 1, #0, NP ) )
ConnectTo( Next( 2, #0+1, NP/2 )

 

Example 2

In this 2-d grid example each collector needs to make a sub set of connections the the data store depending on the its element number. 

 

 

 

Each collector n,m connects to its 8 neighbours and its self (in a specific order).

The connections also need to wrap around at the each edges/corners of the grid.

To configure this connection using switches and cases would be extremely arduous and only possible if N and M where known (and small).

We can make this connection using macros. To do this we need to generate macro functions with the following formats (since it must generate 2 values and used to initialize a array of constants)  

#define G( X )      something         // NB. G and H could be the same
#define H( Y )      something

#define F( X, Y )   G( X ), H( Y )    // NB. no outer brackets around the G,H functions

generated code

const Uns elem[2] = { F( e1, e0 ) };

which after macro substitution is equivalent to

const Uns elem[2] = { G( e1 ), H( e0 ) };

 

Thus for this example we would define the macros (in ProjectHeader.hpp)

#define N  10
#define M  10

#define Wrap( Xi, X )      ( ((X)+(Xi)) % (X) )
#define Wrap2( Ni, Mi )    Wrap( (Ni), (N) ), Wrap( (Mi), (M) )

 

and use the Wizard to make the following connections

 

This example shows the use of overriding the dimension field

   Calculated Dimension = [9]

   User Specified Dimension = [3][3]

This allows the connection access functions to be generated to match the logic of the problem.

Dimensional Circuits

When making connections to objects in circuits that have dimensions, the ConnectTo entries are simply extended to the left to incorporate the circuit dimension. However, when making connections from objects whose parent circuit has dimensions, the values ^#n can be used to extract the element ids of the Circuit.

Eg.

PinIn connects to PinOut. Although PinIn has dimension [1], its parent circuit has dimension [2]. To enable each PinIn to connect to each PinOut, we need to specify ^#0 in the Connect.

Thus

   MySub[0]::PinIn connects to MyCircuit::PinOut[0]

   MySub[1]::PinIn connects to MyCircuit::PinOut[1]